
#include <malloc.h>

#include "nodo.h"
#include "recepcion-asignacion.h"
#include "ordenamiento-inicial.h"
#include "ordenamiento-adicional.h"
#include "envio-resultado.h"

#include "../varios/log.h"
#include "../varios/mpi-utiles.h"


/*
 * Implementacion de funcion de los nodos
 */
double nodo() {

    /* Paso 1: Obtenemos el asignacion de trabajo */
    LOGGER("Iniciamos el nodo de trabajo obteniendo el asignacion");
    struct ASIGNACION_NODO *asignacion = obtenerAsignacionTrabajo();
    LOGGER("Asignacion obtenido: %s", imprimirAsignacion(asignacion));
    
    /* Paso 2: Obtenemos el vector inicial que nos envia el coordinador y lo ordenamos */
    LOGGER("Obtenemos el vector inicial de tamaño %l", asignacion->tamVectorInicial);
    struct VECTOR *vector = obtenerVectorInicial(asignacion->tamVectorInicial);
    LOGGER("Vector inicial obtenido: %s", imprimirVector(vector));
        
    /* Paso 3: Si es necesario, ordenamos los vectores que nos envíen otros nodos y lo juntamos con el nuestro */
    if (asignacion->cantOriginesIntermedios > 0) {
        LOGGER("Recibimos los vectores remotos y los ordenamos");
        struct VECTOR *vectorIntermedio = ordenarVectoresRemotos(vector, asignacion->cantOriginesIntermedios,
                asignacion->originesIntermedios, asignacion->tamVectoresIntermedios);
        vector = vectorIntermedio;
        LOGGER("Vectores intermedios mergeados. %s", imprimirVector(vector));
    }
    
    /* Paso 4: Enviamos el vector resultante al destino final designado */
    LOGGER("Enviamos el vector resultante al destino %d", asignacion->destinoFinal);
    enviarVectorFinal(vector, asignacion->destinoFinal);
    eliminarVector(vector);
            
    LOGGER("Procesamiento finalizado");
    free(asignacion->originesIntermedios);
    free(asignacion->tamVectoresIntermedios);
    free(asignacion);
    
    LOGGER("Nodo finalizado");
    return obtenerTiempoEspera();
    
}
